/**
 *
 */
package com.framework.util;

import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.http.HttpSession;

import org.apache.log4j.Logger;

/**
 * @author ferney
 *
 */
public class Util {

	private static Logger log = Logger.getLogger(Util.class);

	public static String getEdad(Date fecha_nacimiento, String unidad_medidad,
			boolean sw) {

		String edad = "";

		Date fecha_actual = new Date();
		double mSecDiff = Math.abs(fecha_actual.getTime()
				- fecha_nacimiento.getTime()) / 1000;

		double AgeDays = mSecDiff / 86400;
		double AgeMonth = AgeDays / 29.4375;
		double AgeYears = AgeDays / 365.24;
		// AgeYears = Math.floor(AgeYears);
		// AgeDays = Math.round(AgeDays * 10) / 10;
		// AgeMonth = Math.round(AgeMonth * 10) / 10;
		double AgeHour = AgeDays * 24;
		double AgeMinute = AgeHour * 60;
		AgeMinute = Math.round(AgeMinute * 10) / 10;

		if (unidad_medidad.equals("1")) {
			if ((int) AgeYears != 1) {
				edad = (int) AgeYears + (sw ? " Años" : "");
			} else {
				edad = (int) AgeYears + (sw ? " Año" : "");
			}
		} else if (unidad_medidad.equals("2")) {
			if ((int) AgeMonth != 1) {
				edad = (int) AgeMonth + (sw ? " Meses" : "");
			} else {
				edad = (int) AgeMonth + (sw ? " Mes" : "");
			}
		} else if (unidad_medidad.equals("3")) {
			if ((int) AgeDays != 1) {
				edad = (int) AgeDays + (sw ? " Dias" : "");
			} else {
				edad = (int) AgeDays + (sw ? " Dia" : "");
			}
		} else if (unidad_medidad.equals("5")) {
			if ((int) AgeHour != 1) {
				edad = (int) AgeHour + (sw ? " Horas" : "");
			} else {
				edad = (int) AgeHour + (sw ? " Hora" : "");
			}
		} else if (unidad_medidad.equals("6")) {
			if ((int) AgeHour != 1) {
				edad = (int) AgeMinute + (sw ? " Minutos" : "");
			} else {
				edad = (int) AgeMinute + (sw ? " Minuto" : "");
			}
		}

		return edad;
	}

	public static String getEdad(String fecha, String unidad_medidad, boolean sw) {

		String edad = "";

		Date fecha_actual = new Date();
		Date fecha_nacimiento = new Date();

		int dia = 0, mes = 0, anio = 0, hora = 0, minutos = 0;

		StringTokenizer st = new StringTokenizer(fecha.replace("-", "/"), "/");
		int cont = 0;
		while (st.hasMoreTokens()) {
			String tokens = st.nextToken();
			if (cont == 0) {
				dia = Integer.parseInt(tokens, 10);
			} else if (cont == 1) {
				mes = Integer.parseInt(tokens, 10);
			} else if (cont == 2) {
				anio = Integer.parseInt(tokens, 10);
			} else if (cont == 3) {
				hora = Integer.parseInt(tokens, 10);
			} else if (cont == 4) {
				minutos = Integer.parseInt(tokens, 10);
			}
			cont++;
		}
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(Calendar.YEAR, anio);
		calendar.set(Calendar.MONTH, (mes - 1));
		calendar.set(Calendar.DAY_OF_MONTH, dia);
		calendar.set(Calendar.HOUR_OF_DAY, hora);
		calendar.set(Calendar.MINUTE, minutos);
		fecha_nacimiento.setTime(calendar.getTimeInMillis());

		double mSecDiff = Math.abs(fecha_actual.getTime()
				- fecha_nacimiento.getTime()) / 1000;

		double AgeDays = mSecDiff / 86400;
		double AgeMonth = AgeDays / 30.4375;
		double AgeYears = AgeDays / 365.24;

		AgeYears = Math.floor(AgeYears);

		AgeDays = Math.round(AgeDays * 10) / 10;
		AgeMonth = Math.round(AgeMonth * 10) / 10;
		double AgeHour = AgeDays * 24;
		double AgeMinute = AgeHour * 60;
		AgeMinute = Math.round(AgeMinute * 10) / 10;

		if (unidad_medidad.equals("1")) {
			edad = (int) AgeYears + (sw ? " Años" : "");
		} else if (unidad_medidad.equals("2")) {
			edad = (int) AgeMonth + (sw ? " Meses" : "");
		} else if (unidad_medidad.equals("3")) {
			edad = (int) AgeDays + (sw ? " Días" : "");
		} else if (unidad_medidad.equals("5")) {
			edad = (int) AgeHour + (sw ? " Horas" : "");
		} else if (unidad_medidad.equals("6")) {
			edad = (int) AgeMinute + (sw ? " Minutos" : "");
		}

		return edad;
	}

	public static Map<String, Integer> getEdadYYYYMMDD(Date fecha) {
		return getEdadYYYYMMDD(fecha, null);
	}

	public static Map<String, Integer> getEdadYYYYMMDD(Date fecha,
			Date fecha_comparacion) {

		Date fecha_actual = new Date();
		Date fecha_nacimiento = fecha;

		if (fecha_comparacion != null) {
			fecha_actual = fecha_comparacion;
		}

		Long mSecDiff = Math.abs(fecha_actual.getTime()
				- fecha_nacimiento.getTime()) / 1000;

		Long ageDays = mSecDiff / 86400;
		Double ageMonth = ageDays / 30.4375;
		Double ageYears = ageDays / 365.24;

		ageYears = Math.floor(ageYears);
		ageDays = new Long(Math.round(ageDays * 10) / 10);
		ageMonth = new Double(Math.round(ageMonth * 10) / 10);
		Double ageHour = new Double(ageDays * 24);
		Double ageMinute = ageHour * 60;

		Map<String, Integer> mapa_edades = new HashMap<String, Integer>();
		mapa_edades.put("anios", ageYears.intValue());
		mapa_edades.put("meses", ageMonth.intValue());
		mapa_edades.put("dias", ageDays.intValue());
		mapa_edades.put("horas", ageHour.intValue());
		mapa_edades.put("minutos", ageMinute.intValue());
		return mapa_edades;
	}

	public static String getEdadPrsentacion(Timestamp fecha_nacimiento) {
		return getEdadPrsentacion(fecha_nacimiento, null);
	}

	public static String getEdadPrsentacion(Timestamp fecha_nacimiento,
			Timestamp fecha_actual) {
		Map<String, Integer> mapa_edades = Util.getEdadYYYYMMDD(
				fecha_nacimiento, fecha_actual);

		Integer anios = mapa_edades.get("anios");
		Integer meses = mapa_edades.get("meses");
		Integer dias = mapa_edades.get("dias");

		if (anios.intValue() == 0 && meses.intValue() == 0) {
			return (dias + (dias == 1 ? " dia" : " días"));
		} else if (anios.intValue() == 0) {
			return (meses + (meses == 1 ? " mes (" : " meses (")
					+ (dias + (dias == 1 ? " día" : " días")) + ")");
		} else {
			int current_meses = meses.intValue() - (anios.intValue() * 12);
			return (anios + (anios == 1 ? " año" : " años") + (current_meses != 0 ? (" y "
					+ current_meses + (current_meses == 1 ? " mes " : " meses"))
					: ""));
		}
	}

	public static String getEdadPrsentacionSimple(Timestamp fecha_nacimiento,
			Timestamp fecha_actual) {
		Map<String, Integer> mapa_edades = Util.getEdadYYYYMMDD(
				fecha_nacimiento, fecha_actual);

		Integer anios = mapa_edades.get("anios");
		Integer meses = mapa_edades.get("meses");
		Integer dias = mapa_edades.get("dias");

		if (anios.intValue() == 0 && meses.intValue() == 0) {
			return (dias + (dias == 1 ? " día" : " días"));
		} else if (anios.intValue() == 0) {
			return (meses + (meses == 1 ? " Mes" : " Meses"));
		} else {
			return (anios + (anios == 1 ? " año" : " años"));
		}
	}

	public static String getUnidadMedidaEdad(Timestamp fecha_nacimiento,
			Timestamp fecha_actual) {
		Map<String, Integer> mapa_edades = Util.getEdadYYYYMMDD(
				fecha_nacimiento, fecha_actual);

		Integer anios = mapa_edades.get("anios");
		Integer meses = mapa_edades.get("meses");
		Integer dias = mapa_edades.get("dias");
		Integer horas = mapa_edades.get("horas");

		if (anios.intValue() == 0 && meses.intValue() == 0
				&& dias.intValue() == 0 && horas.intValue() == 0) {
			// minutos
			return "6";
		} else if (anios.intValue() == 0 && meses.intValue() == 0
				&& dias.intValue() == 0) {
			// horas
			return "5";
		} else if (anios.intValue() == 0 && meses.intValue() == 0) {
			// dias
			return "3";
		} else if (anios.intValue() == 0) {
			// meses
			return "2";
		} else {
			// años
			return "1";
		}
	}

	public static int getDiasDiferencia(Date fecha_nacimiento, Date fecha_actual) {
		Map<String, Integer> mapa_edades = Util.getEdadYYYYMMDD(
				fecha_nacimiento, fecha_actual);
		Integer dias = mapa_edades.get("dias");
		return dias != null ? dias : 0;
	}

	public static int getDiferenciaEntreMeses(Date fecha_incio, Date fecha_final) {
		double mSecDiff = Math.abs(fecha_incio.getTime()
				- fecha_final.getTime()) / 1000;

		double ageDays = mSecDiff / 86400;
		double ageMonth = ageDays / 30.4375;

		return (int) Math.round(ageMonth * 10) / 10;
	}

	/**
	 * Agrega comillas simples al inicio y final de una cadena, cambiando
	 * comillas dobles o comillas no abiertas/cerradas en caso de tenerlas.
	 *
	 * @param cadena
	 *            cadena de texto a la que se le va a agregar las comillas.
	 * @return cadena con comillas simples al inicio y final.
	 */
	public static String agregarComillas(String cadena) {
		String c = "'";

		// Elimina espacios del inicio y fin
		cadena = cadena.trim();

		// Verifica si contiene comillas (dobles o sencillas) y se elimina para
		// "limpiar el texto"
		Pattern p = Pattern.compile("^[\"\']?(.+?)[\"\']?$");
		Matcher m = p.matcher(cadena);
		if (m.find()) {
			// Reemplaza agrega al texto limpio el caracter correspondiente al
			// inicio y al final.
			cadena = c + m.group(1) + c;
		}
		return cadena;
	}

	public static void mostrarParametros(String titulo,
			Map<String, Object> parametros) {
		log.info(titulo + " -------***");
		for (String key_map : parametros.keySet()) {
			Object dato = parametros.get(key_map);
			if (dato instanceof Map) {
				mostrarParametros(key_map, (Map<String, Object>) dato);
			} else {
				log.info(key_map + " ===> " + parametros.get(key_map));
			}

		}
	}

	public static void mostrarAtributos2(HttpSession session) {
		log.info("session ===> " + session.getId());
	}

}
